ホームに戻る
出典 :
関連 :
目次 :
MVVM Toolkitとは
NuGetで公開されているライブラリで、MVVMパターンの構築を支援する機能を備えており、
INotifyPropertyChanged
やICommand
を簡単に実装できる。
MVVM Toolkitが提供する機能
提供されるクラス |
名前空間 |
担当機能 |
ObservableObject |
CommunityToolkit.Mvvm.ComponentModel |
INotifyPropertyChanged を実装したオブジェクトの基底クラス |
RelayCommand |
CommunityToolkit.Mvvm.Input |
ICommand の実装 |
WeakReferenceMessenger |
CommunityToolkit.Mvvm.Messeging |
Messenger (詳細割愛) |
IoC |
CommunityToolkit.Mvvm.DependencyInjection |
DI 、IoC (詳細割愛) |
主な仕組み

ViewModelとして用いるクラスを
ObservableObject
の派生クラスとして定義し、
データバインディングのソースとして用いるプロパティ(変更通知プロパティ)を含める。
コマンドは
ICommand
として作成し、これをコマンドバインディングのソースとする。
準備

CommunityToolkit.Mvvm がインストールされていない場合は、Nuget より取得する。
実装例(MVVM Toolkit Ver.7)
変更通知プロパティ
ViewModel : MainWindowVM.cs
using CommunityToolkit.Mvvm.ComponentModel; //< ObservableObject の名前解決
// ViewModel : ObservableObject を継承
public class MainWindowVM : ObservableObject
{
// Name のバッキングフィールド
private string _name;
// プロパティ(バインドソース)
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
}
View(XAML) : MainWindow.xaml (抜粋)
<!-- TextBlock.Text を DataContext の Name プロパティにバインド -->
<
TextBlock Text=
"{Binding Name}" />
ViewModel として用いるクラスは、ObservableObject
を継承して作成する。
ObservableObject
はINotifyPropertyChanged
を実装している。
プロパティの値を変更(set
)した際は View への通知を行うため、SetProperty()
を呼び出している。
また、INofityPropertyChanged
を実装していない Model クラスをラップしてPropertyChanged
に反応させることも可能である。
Model : Person.cs
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
ViewModel : MainWindowVM.cs
using CommunityToolkit.Mvvm.ComponentModel;
public class MainWindowVM : ObservableObject
{
private Person _person;
public int Age
{
get => _person.Age;
set => SetProperty( _person.Age, value, _person, (p, newval) => p.Age = newval );
}
public string Name
{
get => _person.Name;
set => SetProperty( _person.Name, value, _person, (p, newval) => p.Name = newval );
}
}
この場合のSetProperty()
の引数は、元の値、新しい値、対象オブジェクト、値更新時のコールバック、である。
_person のプロパティ更新をコールバック内で行っている点に注意。
コマンド
ViewModel : MainWindowVM.cs
using CommunityToolkit.Mvvm.ComponentModel; //< ObservableObject の名前解決
using CommunityToolkit.Mvvm.Input; //< RelayCommand の名前解決
public class MainWindowVM : ObservableObject
{
// プロパティ(バインドソース)
public ICommand ClickCommand { get; }
// コンストラクタ
public MainWindowVM()
{
ClickCommand = new RelayCommand(Click);
}
// コマンドとしてに実行したい処理
private void Click() { Name = ""; }
}
コマンドは
ICommand
として作成する。
実際にコマンドとして実行したい処理は Click() であるため、ViewModel のコンストラクタ中で
RelayCommand
化してプロパティに関連づける。
RelayCommand
のコンストラクタには複数のオーバーロードが存在し、
CanExecute
や
CommandParameter
を指定することも可能である。
(詳細は
リファレンス参照。)
Ver.8での変更
MVVM Toolkit Ver.8では各種機能をカスタム属性として利用できるようになり、コードの記述を大幅に削減できるようになった。
Ver.7での記法も引き続き有効である。
|
Ver.7 |
Ver.8 |
ViewModel クラス定義 |
 |
 |
- ViewModel は
ObservableObject を継承
|
- ViewModel に
INotifyPropertyChanged 属性を付与
- クラスを
partial 修飾 (コードジェネレータにより追加コードが自動生成される)
|
変更通知 プロパティ |
 |
 |
- バインドソースとバッキングフィールドを記述
- バインドソースの
set 内でSetProperty() をコール
|
- バッキングフィールドのみを記述
- バッキングフィールドに
ObservableProperty 属性を付与
- バインドソース Name は自動的に生成される
|
コマンド |
 |
 |
|
- ハンドラのみを記述
- ハンドラに
RelayCommand 属性を付与
- バインドソース GreetCommand は自動的に生成される
|
注意点
変更通知プロパティ、コマンドともにバインドソースとなるプロパティはコードジェネレータにより自動的に生成される。
その際、変更通知プロパティはバッキングフィールドの先頭文字を大文字にしたもの
(例 : name ⇒ Name)
コマンドはハンドラメソッドの後に Command を付与したものとなる。
(例 : Greet ⇒ GreetCommand)
変更通知プロパティの変更直前、直後に処理を行いたい場合、部分メソッドOn####Changing()
、On####Changed()
を定義しておくと、
それぞれ実行されるようになる。
( #### はプロパティ名)
[ObservableProperty]
private string name;
partial void OnNameChanging(string name)
=>Console.WriteLine($"Nameプロパティが {name} に変更されようとしてます");
partial void OnNameChanged(string name)
=>Console.WriteLine($"Nameプロパティが {name} に変更されました");